package top.byfree.jbyan.find.result;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.stream.Collectors;

import static top.byfree.jbyan.find.FindApplication.ARGS;

/**
 * 查询多个key使用的结果集
 *
 * @author jbyan
 * @since 2023/8/10
 */
public class MoreKeyResultSet implements ResultSet {

    /* 用优先队列保存找到的索引和key, 按照索引进行排序 */
    private final PriorityQueue<KeyEntry> keyEntryPriorityQueue = new PriorityQueue<>(Comparator.comparing(KeyEntry::getIndex));

    /* 保存当前击中的行集合 */
    private final List<Line> resultList = new ArrayList<>();

    /* 保存当前结果集结尾索引 */
    private int endIndex = 0;

    @Override
    public boolean isOpen() {
        return keyEntryPriorityQueue.size() != 0;
    }

    @Override
    public boolean isEnd() {
        // 优先队列大小小于关键字集合大小，则不可能匹配所有关键字直接返回false
        int size = ARGS.getPosArgs().size();
        if (keyEntryPriorityQueue.size() < size)
            return false;
        // 对优先队列去重后比较集合大小
        return keyEntryPriorityQueue.stream().distinct().count() == size;
    }

    /**
     * 向优先队列中添加一条记录
     *
     * @param index 索引
     * @param key   击中的关键字
     */
    public void addToPriorityQueue(int index, String key) {
        endIndex = index;
        keyEntryPriorityQueue.add(KeyEntry.create(index, key));
    }

    /**
     * 获取优先队列中第一个元素的索引
     * @return 索引
     */
    public int getFirstIndex() {
        return keyEntryPriorityQueue.element().getIndex();
    }

    /**
     * 移除优先队列的第一个元素
     */
    public void removeFirstElement() {
        keyEntryPriorityQueue.poll();
    }


    @Override
    public void addLine(Line line) {
        resultList.add(line);
    }

    @Override
    public List<Line> getLines() {
        int firstIndex = getFirstIndex();
        return this.resultList.stream()
                .filter(line -> line.getIndex() >= firstIndex && line.getIndex() <= endIndex)
                .collect(Collectors.toList());
    }

    @Override
    public String getResult() {
        KeyEntry element = this.keyEntryPriorityQueue.element();
        Integer startIndex = element.getIndex();
        if (startIndex == endIndex)
            return Integer.toString(startIndex);
        return startIndex > endIndex ? endIndex + "-" + startIndex : startIndex + "-" + endIndex;
    }
}
